#include "ZombieSwarm.h"
#include "ZombieManager.h"

// Métodos privados ----------------------------------------------------

void
ZombieSwarm::updateSwarmCenter() {

  OpenSteer::Vec3 swarmCenter(0, 0, 0);

  for (_zombiesIt = _zombies.begin();
       _zombiesIt != _zombies.end();
       _zombiesIt++)
    swarmCenter += (*_zombiesIt)->position();

  swarmCenter /= _zombies.size();

  _swarmCenter = swarmCenter;
}

// Constructores y destructores ----------------------------------------

ZombieSwarm::ZombieSwarm(btDiscreteDynamicsWorld* pWorld,
                         Ogre::SceneManager* pSceneManager,
                         OpenSteer::Vec3 position,
                         ZombieManager* pZombieManager,
                         Human* pHuman) :
  _pWorld(pWorld), _pSceneManager(pSceneManager), _swarmCenter(position),
  _pZombieManager(pZombieManager), _pHuman(pHuman) {

  _maxDistance = 0;
  _nZombies = 0;
}

void
ZombieSwarm::update(const float currentTime, const float elapsedTime) {

  updateSwarmCenter();
}

void
ZombieSwarm::updateMaxDistance() {

  // Distancia máxima es igual a la diagonal del cuadrado que formarian
  // los zombis si los colocaramos formando tal figura
  _maxDistance = (_nZombies / Ogre::Math::Sqrt(_nZombies)) *
    Ogre::Math::Sqrt(2);
}

OpenSteer::Vec3
ZombieSwarm::randomPositionInSwarm() const {

  return _swarmCenter + OpenSteer::randomVectorOnUnitRadiusXZDisk() *
    _maxDistance;
}

void
ZombieSwarm::addZombie(Zombie* pZombie) {

  _zombies.push_back(pZombie);
  _nZombies++;

  updateMaxDistance();
}

void
ZombieSwarm::removeZombie(Zombie* pZombie) {

  _zombies.remove(pZombie);
  _nZombies--;

  updateMaxDistance();

  if (_nZombies == 0)
    _pZombieManager->deleteSwarm(this);
}
